package com.msb.dongbao.portal.web.custom;

import com.baomidou.kaptcha.Kaptcha;
import com.baomidou.kaptcha.exception.KaptchaRenderException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author: may
 * @date: 2021年05月28日 23:48
 */
@Component
public class MyGoogleKaptcha implements Kaptcha {
    private static final Logger log = LoggerFactory.getLogger(com.baomidou.kaptcha.GoogleKaptcha.class);
    private DefaultKaptcha kaptcha;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    StringRedisTemplate redisTemplate;

    public MyGoogleKaptcha(DefaultKaptcha kaptcha) {
        this.kaptcha = kaptcha;
    }

    public String render() {
        this.response.setDateHeader("Expires", 0L);
        this.response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        this.response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        this.response.setHeader("Pragma", "no-cache");
        this.response.setContentType("image/jpeg");
        String sessionCode = this.kaptcha.createText();

        try {
            ServletOutputStream out = this.response.getOutputStream();
            Throwable var3 = null;

            String var4;
            try {
                //this.request.getSession().setAttribute("KAPTCHA_SESSION_KEY", sessionCode);
                //this.request.getSession().setAttribute("KAPTCHA_SESSION_DATE", System.currentTimeMillis());

                redisTemplate.opsForValue().set("may", sessionCode);

                ImageIO.write(this.kaptcha.createImage(sessionCode), "jpg", out);
                var4 = sessionCode;
            } catch (Throwable var14) {
                var3 = var14;
                throw var14;
            } finally {
                if (out != null) {
                    if (var3 != null) {
                        try {
                            out.close();
                        } catch (Throwable var13) {
                            var3.addSuppressed(var13);
                        }
                    } else {
                        out.close();
                    }
                }

            }

            return var4;
        } catch (IOException var16) {
            throw new KaptchaRenderException(var16);
        }
    }

    public Map<String, String> renderBase64() {
        ByteArrayOutputStream out = null;
        Map<String, String> map = new HashMap<>();
        try {
            String sessionCode = this.kaptcha.createText();

            //ServletOutputStream out = this.response.getOutputStream();
            out = new ByteArrayOutputStream();

            ImageIO.write(this.kaptcha.createImage(sessionCode), "jpg", out);

            byte[] bytes = out.toByteArray();

            String base64Str = Base64.getEncoder().encodeToString(bytes);

            String uuid = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set(uuid, sessionCode);

            map.put("base64Str", base64Str);
            map.put("uuid", uuid);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return map;
    }

    public boolean validate(String code) {
        return this.validate(code, 900L);
    }

    public boolean validate(String code, long second) {
        if (StringUtils.isBlank(code) || "null".equals(code)) {
            throw new NullPointerException("code");
        } else {
            String sessionCode = redisTemplate.opsForValue().get("may");
            if (code.equals(sessionCode)) {
                redisTemplate.delete("may");
                return true;
            }
            return false;
        }
    }

    public boolean validateBase64(String code, String uuid) {
        return this.validateBase64(code, uuid, 900);
    }

    public boolean validateBase64(String code, String uuid, long second) {
        if (StringUtils.isBlank(code) || "null".equals(code)) {
            throw new NullPointerException("code");
        } else {
            String sessionCode = redisTemplate.opsForValue().get(uuid);
            if (code.equals(sessionCode)) {
                redisTemplate.delete(uuid);
                return true;
            }
            return false;
        }
    }
}

